package ru.mcfr.oxygen.framework.utils;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.nio.charset.Charset;

/**
 * Created by IntelliJ IDEA.
 * User: ws
 * Date: 05.07.11
 * Time: 17:50
 * To change this template use File | Settings | File Templates.
 */
public class XmlTool {

    public static String xmlDocumentToString(Document XMLDoc) throws Exception {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        StreamResult result = new StreamResult(new StringWriter());
        DOMSource source = new DOMSource(XMLDoc);
        transformer.transform(source, result);
        return result.getWriter().toString();
    }

    public static Document stringXMLtoDocument(String xmlText) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        return db.parse(new ByteArrayInputStream(xmlText.getBytes("UTF-8")));
    }

    public static Document stringXMLtoDocument2(String xmlText) throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        return db.parse(new ByteArrayInputStream(xmlText.getBytes("UTF-8")));
    }

    public static String xmlNodeToString(Node node) {
        String res = "";
        OutputFormat opfrmt = new OutputFormat("XML", "UTF-8", false);
        opfrmt.setPreserveSpace(false);
        opfrmt.setOmitDocumentType(true);
        opfrmt.setOmitXMLDeclaration(true);
        StringWriter stringOut = new StringWriter();
        XMLSerializer serial = new XMLSerializer(stringOut, opfrmt);

        try {
            serial.asDOMSerializer();
            serial.serialize(node);
            res = stringOut.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;
    }

    public static Element xmlFragmentToDOMElement(String xmlFragment) throws Exception {
        String mainFragment = "<fragmentRoot>" + xmlFragment + "</fragmentRoot>";
        Document doc = XmlTool.stringXMLtoDocument(mainFragment);
        if (doc == null)
            return null;
        return doc.getDocumentElement();
    }

    public static void docToFile(Document doc, String fileName) throws Exception {
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        StreamResult result = new StreamResult(new StringWriter());
        DOMSource source = new DOMSource(doc);
        transformer.transform(source, result);
        String data = result.getWriter().toString();

        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(fileName), Charset.forName("UTF-8"))
        );
        writer.write(data);
        writer.close();
    }

    public static Document docFromFile(String fileName) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setValidating(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        db.setErrorHandler(new ErrorHandler(){

            @Override
            public void warning(SAXParseException exception) throws SAXException {
                System.out.println(exception.getMessage() + "at column:" + exception.getColumnNumber() + " row:" + exception.getLineNumber());
            }

            @Override
            public void error(SAXParseException exception) throws SAXException {
                System.out.println(exception.getMessage() + "at column:" + exception.getColumnNumber() + " row:" + exception.getLineNumber());
            }

            @Override
            public void fatalError(SAXParseException exception) throws SAXException {
                System.out.println(exception.getMessage() + "at column:" + exception.getColumnNumber() + " row:" + exception.getLineNumber());
            }
        });
        return db.parse(new FileInputStream(fileName));
    }


}
